package com.zeta.system.poi.listener;

import cn.hutool.core.util.StrUtil;
import cn.idev.excel.context.AnalysisContext;
import cn.idev.excel.exception.ExcelDataConvertException;
import cn.idev.excel.read.listener.ReadListener;
import com.zeta.system.model.poi.SysDictItemImportVO;
import com.zeta.system.service.ISysDictItemService;
import lombok.extern.slf4j.Slf4j;
import org.zetaframework.base.exception.ExcelVerifyException;
import org.zetaframework.base.utils.ExcelAssert;

import java.util.ArrayList;
import java.util.List;

/**
 * 字典项Excel导入监听
 *
 * @author gcc
 */
@Slf4j
public class SysDictItemImportListener implements ReadListener<SysDictItemImportVO> {

    private final ISysDictItemService service;
    public SysDictItemImportListener(ISysDictItemService service) {
        this.service = service;
    }

    /** 待批量导入的字典项列表 */
    private final List<SysDictItemImportVO> importDictItemList = new ArrayList<>();

    /**
     * 对每一行数据进行解析
     *
     * @param data    一行的数据
     * @param context analysis context
     */
    @Override
    public void invoke(SysDictItemImportVO data, AnalysisContext context) {
        ExcelAssert.notNull(data.getDictId(), "字典id不能为空");
        ExcelAssert.notBlank(data.getName(), "字典项不能为空");
        ExcelAssert.notBlank(data.getValue(), "字典项值不能为空");
    }

    /**
     * 所有数据读取完成后调用此方法
     *
     * @param context analysis context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 批量保存字典项
        service.batchImportDictItem(importDictItemList);
        importDictItemList.clear();
    }

    /**
     * 当任何一个侦听器执行错误报告时，所有侦听器都会收到此方法。
     * <p>
     * 注意：<br>
     * 如果在此处抛出异常，则整个读取将终止。
     *
     * @param exception 异常
     * @param context 上下文
     * @throws Exception
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        log.error("excel导入数据处理时发生异常: {}", exception.getMessage());

        if (exception instanceof ExcelDataConvertException convertException) {
            throw new ExcelVerifyException(StrUtil.format("第{}行第{}列数据转换错误：{}", convertException.getRowIndex(), convertException.getColumnIndex(), convertException.getMessage()));
        }

        throw exception;
    }
}
